
use clap::Parser;
use crate::source::{SourceConf, source_run};
use crate::logical_plan::work_space::{WorkSpaceConf, work_space_run};
use crate::logical_plan::work_node::{WorkNodeConf, work_node_run};
use once_cell::sync::OnceCell;
use crate::logical_plan::work_node::util::ErrResult;
use std::collections::VecDeque;

#[derive(Deserialize)]
pub struct NormalNodeConf{
    pub sync_channel_size: usize,
    pub async_channel_size: usize,
}

#[derive(Deserialize)]
pub struct EventFlowNodeConf{
    pub source: Vec<SourceConf>,
    pub work_space: Vec<WorkSpaceConf>,
    pub work_node: Option<Vec<WorkNodeConf>>,
}

#[derive(Deserialize)]
pub struct EventFlowNormalConf{
    pub node: NormalNodeConf,
    pub snowflake_machine_id: usize,
    pub snowflake_node_id: usize,
}

#[derive(Parser, Debug)]
#[clap(author, version, about, long_about = None)]
pub struct EventFlowCmdConf{
    #[clap(short='l', long="log4rs", default_value="./conf/log4rs.yaml")]
    pub log4rs_yaml: String,
    #[clap(short='n', long="node", default_value="./conf/node.yaml")]
    pub node_yaml: String,
    #[clap(short='c', long="conf", default_value="./conf/normal.toml")]
    pub normal_toml: String,
}

lazy_static!{
    pub static ref EVENT_FLOW_CMD_CONF_INSTANCE: EventFlowCmdConf = {
        EventFlowCmdConf::parse()
    };
    pub static ref EventFlowNormalConfInstance: EventFlowNormalConf = {
        let toml_string = match std::fs::read_to_string(std::path::Path::new(&EVENT_FLOW_CMD_CONF_INSTANCE.normal_toml)){
            Ok(t) => {t},
            Err(e) => {
               error!("normal conf init failed [{:?}]", e);
               std::process::exit(-1);
            },
        };

        match toml::from_str(&toml_string) {
            Ok(t) => {
                t
            },
            Err(e) => {
                error!("normal conf toml::from_str failed [{:?}]", e);
                std::process::exit(-1);
            },
        }
    };
    pub static ref EventFlowNodeConfInstance: EventFlowNodeConf = {
        let yaml_string = match std::fs::read_to_string(std::path::Path::new(&EVENT_FLOW_CMD_CONF_INSTANCE.node_yaml)){
            Ok(t) => {t},
            Err(e) => {
                error!("node conf init failed [{:?}]", e);
                std::process::exit(-1);
            },
        };
        match serde_yaml::from_str(yaml_string.as_str()){
            Ok(t) => {t},
            Err(e) => {
                error!("node conf init failed [{:?}]", e);
                std::process::exit(-1);
            },
        }
    };
}

#[derive(Debug)]
pub struct ResultErr{
    desc: VecDeque<String>,
}
impl ResultErr{
    pub fn new(desc: String) -> ResultErr{
        let mut tmp = VecDeque::new();
        tmp.push_back(desc);

        ResultErr{
            desc: tmp,
        }
    }
    pub fn append(&mut self, desc: String){
        self.desc.push_back(desc);
    }
}

pub type MapResult<T> = Result<T,ResultErr>;

pub fn conf_map_run()->MapResult<()>{

    work_node_run()?;

    work_space_run()?;

    source_run()?;


    return MapResult::Ok(());
}

